package com.gs.synedocket.util;

import android.text.TextUtils;

import com.gs.synedocket.apiresult.ApiResultData;
import com.gs.synedocket.callback.IOnSyncListener;
import com.gs.synedocket.constant.AllConstants;
import com.gs.synedocket.constant.HandleCode;
import com.gs.synedocket.constant.SyncStatus;
import com.gs.synedocket.db.dao.LogUtil;
import com.gs.synedocket.db.dto.DocketAccRepDto;
import com.gs.synedocket.db.dto.DocketAddChargeDto;
import com.gs.synedocket.db.dto.DocketQcDto;
import com.gs.synedocket.db.entity.Docket;
import com.gs.synedocket.db.entity.DocketAccRepPhoto;
import com.gs.synedocket.db.entity.DocketPhoto;
import com.gs.synedocket.db.entity.UserTruck;
import com.gs.synedocket.db.sqlite.DBApi;
import com.gs.synedocket.presenter.SyncUploadPresenter;
import com.gs.synedocket.view.ISyncUpload;

import java.util.Date;
import java.util.List;

public class SyncUploadUtil implements ISyncUpload {
    private static final int QC_CHECK = 1;
    private static final int ADD_CHARGE = 2;
    private static final int ACC_REP_PHOTO = 3;
    private static final int ADDITIONAL_PHOTO = 4;
    private static final int SCAN_PHOTO = 5;
//    private boolean isUpload;
    private final SyncUploadPresenter mPresenter;

    private static volatile SyncUploadUtil instance;


    public static SyncUploadUtil getInstance() {
        if (instance == null) {
            synchronized (SyncUploadUtil.class) {
                if (instance == null) {
                    instance = new SyncUploadUtil();
                }
            }
        }
        return instance;
    }

    public SyncUploadUtil() {
        mPresenter = new SyncUploadPresenter();
        mPresenter.attachView(this);
    }
//
//    public boolean isUpload() {
//        return isUpload;
//    }
//
//    public void setUpload(boolean upload) {
//        isUpload = upload;
//    }

    public void upload() {
        Docket bean = DBApi.getInstance().queryDocketSyncList();
        if (bean != null) {
            sendAuto();
            checkScanPhoto(bean);
            return;
        }
        syncUserTruck();
    }

    /**
     * 判断是否有扫描图片或者扫描图片是否已上传
     */
    private void checkScanPhoto(Docket bean) {
        String scanPhoto = bean.getScanPhoto();
        if (!TextUtils.isEmpty(scanPhoto) && StringUtil.isLocalPhoto(scanPhoto)) {
            mPresenter.upload(bean, scanPhoto, SCAN_PHOTO);
            return;
        }
        checkDocketQc(bean);
    }

    /**
     * 判断QC里面的图片是否都已上传
     */
    private void checkDocketQc(Docket bean) {
        DocketQcDto docketQc = bean.getDocketQc();
        if (docketQc != null) {
            if (docketQc.getPhoto1() != null && StringUtil.isLocalPhoto(docketQc.getPhoto1())) {
                uploadBase64(bean, docketQc.getPhoto1(), true, QC_CHECK);
                return;
            } else if (StringUtil.isLocalPhoto(docketQc.getPhoto())) {
                uploadBase64(bean, docketQc.getPhoto(), false, QC_CHECK);
                return;
            }
        }
        checkDocketAddCharge(bean);
    }

    /**
     * 判断AddCharge里面的图片是否都已上传
     */
    private void checkDocketAddCharge(Docket bean) {
        DocketAddChargeDto addCharge = bean.getDocketAddCharge();
        if (addCharge != null) {
            if (addCharge.getPhoto1() != null && StringUtil.isLocalPhoto(addCharge.getPhoto1())) {
                uploadBase64(bean, addCharge.getPhoto1(), true, ADD_CHARGE);
                return;
            } else if (StringUtil.isLocalPhoto(addCharge.getPhoto())) {
                uploadBase64(bean, addCharge.getPhoto(), false, ADD_CHARGE);
                return;
            }
        }
        checkDocketPhoto(bean);
    }

    /**
     * 判断Additional里面的图片是否都已上传
     */
    private void checkDocketPhoto(Docket bean) {
        List<DocketPhoto> docketPhotos = bean.getDocketPhotos();
        if (docketPhotos != null && !docketPhotos.isEmpty()) {
            uploadDocketPhoto(bean, docketPhotos, 0, ADDITIONAL_PHOTO);
            return;
        }
        checkDocketAccRep(bean);
    }

    /**
     * 判断AccRep里面的图片是否都已上传
     */
    private void checkDocketAccRep(Docket bean) {
        DocketAccRepDto accRep = bean.getDocketAccRep();
        if (accRep != null) {
            List<DocketPhoto> accRepPhotos = accRep.getDocketAccRepPhotos();
            if (accRepPhotos != null && !accRepPhotos.isEmpty()) {
                uploadDocketPhoto(bean, accRepPhotos, 0, ACC_REP_PHOTO);
                return;
            }
        }
        uploadDocket(bean);
    }

    /**
     * 上傳Photo
     *
     * @param photos 图片组
     * @param flag   ADDITIONAL_PHOTO/ACC_REP_PHOTO
     */
    private void uploadDocketPhoto(Docket bean, List<DocketPhoto> photos, int position, int flag) {
        // 全部上傳完成
        if (position >= photos.size()) {
            if (flag == ADDITIONAL_PHOTO) {
                checkDocketAccRep(bean);
            } else {
                uploadDocket(bean);
            }
            return;
        }
        String photo = photos.get(position).getPhoto();
        if (StringUtil.isLocalPhoto(photo)) {
            mPresenter.upload(bean, photo, photos, position, flag);
            return;
        }
        uploadDocketPhoto(bean, photos, position + 1, flag);
    }

    /**
     * 上传Base64类型的photo
     *
     * @param isTakePhoto 判断照片是签名还是拍照
     * @param flag        QC_CHECK/ADD_CHARGE
     */
    private void uploadBase64(Docket bean, String photo, boolean isTakePhoto, int flag) {
        if (isTakePhoto) {
            photo = RSAUtil.decryptPhoto(photo);
        } else {
            photo = photo.substring(AllConstants.PHOTO_NAME.length());
        }
        mPresenter.uploadBase64(bean, photo, isTakePhoto, flag);
    }

    private void uploadDocket(Docket bean) {
        mPresenter.syncDocket(bean);
    }

    @Override
    public void onSyncDocketSuccess(ApiResultData<String> result, Docket bean) {
        if (result.getStatus() == 2000) {
//            if (bean.getDocketQc() != null) {
//                DBApi.getInstance().updateDocketQcUpload(bean.getDocketQc());
//            }
//            if (bean.getDocketAddCharge() != null) {
//                DBApi.getInstance().updateDocketAddChargeUpload(bean.getDocketAddCharge());
//            }
//            if (bean.getDocketAdditional() != null) {
//                DBApi.getInstance().updateAdditionalUpload(bean.getDocketAdditional());
//            }
//            if (bean.getDocketPhotos() != null && !bean.getDocketPhotos().isEmpty()) {
//                DBApi.getInstance().updateDocketPhotoUpload(bean.getId());
//            }
//            if (bean.getDocketAccRep() != null) {
//                DBApi.getInstance().updateAccRepUpload(bean.getDocketAccRep());
//            }
            // 判断上传期间用户是否处理了单
            Date tableTime = DBApi.getInstance().queryDocketModifyAt(bean.get_id());
            if (bean.getModifyAt() == null || bean.getModifyAt().getTime() == tableTime.getTime()) {
                DBApi.getInstance().updateDocketUpload(bean);
            }
            upload();
        } else {
            uploadError(result.getMessage());
        }
    }

    @Override
    public void onSyncDocketFails(Exception e) {
        uploadFail();
    }

    @Override
    public void onUploadFileSuccess(ApiResultData<String> result, Docket bean, List<DocketPhoto> photos, int position, int flag) {
        if (result.getStatus() != 2000) {
            uploadError(result.getMessage());
            return;
        }
        if (flag == SCAN_PHOTO) {
            bean.setScanPhoto(result.getData());
            DBApi.getInstance().updateDocketScanPhoto(bean);
            // 继续判断QC里面的图片是否都已上传
            checkDocketQc(bean);
        } else {
            DocketPhoto docketPhoto = photos.get(position);
            docketPhoto.setPhoto(result.getData());
            switch (flag) {
                case ADDITIONAL_PHOTO:
                    bean.getDocketPhotos().set(position, docketPhoto);
                    DBApi.getInstance().updateDocketPhoto(docketPhoto);
                    break;
                case ACC_REP_PHOTO:
                    bean.getDocketAccRep().getDocketAccRepPhotos().set(position, docketPhoto);
                    DocketAccRepPhoto accRepPhoto = new DocketAccRepPhoto();
                    accRepPhoto.set_id(docketPhoto.get_id());
                    accRepPhoto.setAccRepId(bean.getDocketAccRep().getId());
                    accRepPhoto.setPhoto(result.getData());
                    DBApi.getInstance().updateAccRepPhoto(accRepPhoto);
                    break;
            }
            uploadDocketPhoto(bean, photos, position + 1, flag);
        }
    }

    @Override
    public void onUploadFileFails(Exception e) {
        uploadFail();
    }

    @Override
    public void onUploadBase64Success(ApiResultData<String> result, Docket bean, boolean isTakePhoto, int flag) {
        if (result.getStatus() != 2000) {
            uploadError(result.getMessage());
            return;
        }
        switch (flag) {
            case QC_CHECK:
                if (isTakePhoto) {
                    bean.getDocketQc().setPhoto1(result.getData());
                    // 签名图片未上传
                    if (StringUtil.isLocalPhoto(bean.getDocketQc().getPhoto())) {
                        uploadBase64(bean, bean.getDocketQc().getPhoto(), false, flag);
                        return;
                    }
                } else {
                    bean.getDocketQc().setPhoto(result.getData());
                }
                DBApi.getInstance().updateDocketQcPhoto(bean.getDocketQc());
                checkDocketAddCharge(bean);
                break;
            case ADD_CHARGE:
                if (isTakePhoto) {
                    bean.getDocketAddCharge().setPhoto1(result.getData());
                    // 签名图片未上传
                    if (StringUtil.isLocalPhoto(bean.getDocketAddCharge().getPhoto())) {
                        uploadBase64(bean, bean.getDocketAddCharge().getPhoto(), false, flag);
                        return;
                    }
                } else {
                    bean.getDocketAddCharge().setPhoto(result.getData());
                }
                DBApi.getInstance().updateDocketAddChargePhoto(bean.getDocketAddCharge());
                checkDocketPhoto(bean);
                break;
        }
    }

    @Override
    public void onUploadBase64Fails(Exception e) {
        uploadFail();
    }

    /**
     * 上傳User Truck
     */
    private void syncUserTruck() {
        List<UserTruck> list = DBApi.getInstance().queryUserTruck();
        if (!list.isEmpty()) {
            sendAuto();
            syncUserTruck(list, 0);
            return;
        }
        uploadSuccess();
    }

    private void syncUserTruck(List<UserTruck> list, int position) {
        if (position >= list.size()) {
            uploadSuccess();
            return;
        }
        mPresenter.syncUserTruck(list, position);
    }

    @Override
    public void onSyncUserTruckSuccess(ApiResultData<String> result, List<UserTruck> list, int position) {
        if (result.getStatus() == 2000) {
            DBApi.getInstance().updateUserTruck(list.get(position), 1);
            syncUserTruck(list, position + 1);
        } else {
            uploadError(result.getMessage());
        }
    }

    @Override
    public void onSyncUserTruckFails(Exception e) {
        uploadFail();
    }

    private void sendAuto() {
        if (SyncStatus.isSync()) {
//        if (isUpload) {
            return;
        }
        SyncStatus.setSync(true);
//        isUpload = true;
        onSyncListener.onSyncListener(HandleCode.MSG_UPLOADING, null);
    }

    private void uploadFail() {
        SPUtil.getInstance().putString(AllConstants.SYNC_TYPE, AllConstants.SYNC_DOCKET_INTERVAL);
//        LogUtil.getInstance().insertOrReplaceData("上傳本地數據失敗：网络异常");
        SyncStatus.setSync(false);
//        isUpload = false;
        onSyncListener.onSyncListener(HandleCode.MSG_UPLOAD_FAIL, null);
    }

    private void uploadError(String msg) {
        SPUtil.getInstance().putString(AllConstants.SYNC_TYPE, AllConstants.SYNC_DOCKET_INTERVAL);
        LogUtil.getInstance().insertOrReplaceData("上傳本地數據失敗：" + msg);
        SyncStatus.setSync(false);
//        isUpload = false;
        onSyncListener.onSyncListener(HandleCode.MSG_UPLOAD_ERROR, msg);
    }

    private void uploadSuccess() {
        SPUtil.getInstance().putString(AllConstants.SYNC_TYPE, AllConstants.SYNC_DOCKET_INTERVAL);
        onSyncListener.onSyncListener(HandleCode.MSG_UPLOAD_SUCCESS, null);
    }

    private IOnSyncListener onSyncListener;

    public void setOnSyncListener(IOnSyncListener onSyncListener) {
        this.onSyncListener = onSyncListener;
    }
}
